package com.youth.config.exception;

import com.youth.result.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * @author: wuxian
 * @date: 2020/1/7 9:26
 */
@RestControllerAdvice
@Slf4j
public class MyExceptionHandle {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResultBean handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
        StringBuilder errorInfo = new StringBuilder();
        BindingResult bindingResult = exception.getBindingResult();
        for (int i = 0; i < bindingResult.getFieldErrors().size(); i++) {
            if (i > 0) {
                errorInfo.append(",");
            }
            FieldError fieldError = bindingResult.getFieldErrors().get(i);
            errorInfo.append(fieldError.getField()).append(" :").append(fieldError.getDefaultMessage());
        }

        //返回BaseResponse
        return new ResultBean(400, errorInfo.toString(), null);
    }


    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResultBean handleConstraintViolationException(ConstraintViolationException exception) {
        StringBuilder errorInfo = new StringBuilder();
        String errorMessage;

        Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
        for (ConstraintViolation<?> item : violations) {
            errorInfo.append(item.getMessage()).append(",");
        }
        errorMessage = errorInfo.toString().substring(0, errorInfo.toString().length() - 1);

        return new ResultBean(400, errorMessage, null);
    }


    @ExceptionHandler(ShiroException.class)
    public ResultBean doHandleShiroException(ShiroException e) {
        log.error("进入shiro异常捕获 {}", e.toString());
        e.printStackTrace();
        ResultBean result = new ResultBean();
        result.setCode(401);
        if (e instanceof IncorrectCredentialsException) {
            result.setMsg("密码不正确");
        } else if (e instanceof UnknownAccountException) {
            result.setMsg("此账户不存在");
        } else if (e instanceof LockedAccountException) {
            result.setMsg("账户已被禁用");
        } else if (e instanceof UnauthenticatedException) {
            result.setMsg("账户未通过鉴权");
        } else if (e instanceof AuthenticationException) {
            result.setMsg("登录失败");
        } else if (e instanceof AuthorizationException) {
            result.setMsg("无权限");
        }
        return result;
    }

    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResultBean businessExceptionHandle(BusinessException e) {
        e.printStackTrace();
        return new ResultBean(500, e.getMessage(), null);
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResultBean FailureExceptionException500(Exception ex) {
        log.error("异常：{}", ex.toString());
        ex.printStackTrace();
        ResultBean resultBean = new ResultBean(500, ex.getMessage(), null);
        return resultBean;
    }
}
